package heap

import (
	"ch06/classpath"
	"fmt"
	"ch06/classfile"
)

type ClassLoader struct {
	cp *classpath.Classpath
	classMap map[string]*Class
}

func NewClassLoader(cp *classpath.Classpath) *ClassLoader {
	return &ClassLoader{
		cp:       cp,
		classMap: make(map[string]*Class),
	}
}

func (self *ClassLoader) LoadClass(name string) *Class{
	if class,ok := self.classMap[name]; ok {
		return class
	}
	return self.loadNonArrayClass(name)
}
func (self *ClassLoader) loadNonArrayClass(name string) *Class {
	data,entry :=self.readClass(name)
	class := self.defineClass(data)
	link(class)
	fmt.Printf("[Loaded %s from %s]",name,entry)
	return class
}

func (self *ClassLoader) readClass(name string ) ([]byte,classpath.Entry) {
	data,entry,err :=self.cp.ReadClass(name)
	if err != nil {
		panic ("java.lang.ClassNotFoundException"+name)
	}
	return data,entry
}

func(self *ClassLoader) defineClass (data []byte) *Class {
	class := parseClass(data)
	class.loader = self
	resoveSuperClass(class)
	resolveInterface(class)
	self.classMap[class.name]=class
	return class
}
func resoveSuperClass(class *Class) {
	class.na
}

func parseClass(data []byte) *Class {
	cf, err := classfile.Parse(data)
	if err != nil {
		panic("java.lang.ClassFormatError")
	}
	return newClass(cf)
}